﻿using fastCSharp;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System;

namespace OnlineJudge
{
    [fastCSharp.emit.dataSerialize(IsReferenceMember = false, IsMemberMap = false)]
    public partial class JudgeItemBase
    {
        public int JudgeId;
        public int TestId;
        public long MemoryUse;
        public int TimeUse;
        public JudgeResult Result;
        public CompileType CompileType;
        public RouterCallback RouterCallback;
    }

    [fastCSharp.emit.dataSerialize(IsReferenceMember = false, IsMemberMap = false)]
    public partial class JudgeReportBase : CompileBase
    {
        public int TimeLimit;
        public int RetryCount;
        public long MemoryLimit;

        public int TimeUse;
        public long MemoryUse;
        public JudgeResult Result;
        public JudgeValue Value
        {
            get { return GetJudgeValue(Result, State); }
        }

        public string ExtInfo;
        public JudgeBreakOn BreakOn;
        public RouterCallback RouterCallback;

        public List<JudgeItemBase> Results;
        public List<int> TestIds;
        public static JudgeValue GetJudgeValue(JudgeResult result, JudgeState state)
        {
            switch (result)
            {
                case JudgeResult.Accepted:
                    return JudgeValue.Accepted;
                case JudgeResult.Blocked:
                case JudgeResult.TimeLimitExceed:
                    return JudgeValue.TimeLimitExceed;
                case JudgeResult.CreateProcess:
                case JudgeResult.RunTimeError:
                    return JudgeValue.RunTimeError;
                case JudgeResult.WrongAnswer:
                    return JudgeValue.WrongAnswer;
                case JudgeResult.Retry:
                case JudgeResult.DataFileLost:
                case JudgeResult.ProblemError:
                case JudgeResult.FormatError:
                    return JudgeValue.JudgeError;
                case JudgeResult.MemoryLimitExceed:
                    return JudgeValue.MemoryLimitExceed;
                case JudgeResult.ChallangeFail:
                case JudgeResult.DataError:
                    return JudgeValue.ChallangeFail;
                case JudgeResult.DataOk:
                    return JudgeValue.ChallangeSucceed;
            }

            switch (state)
            {
                case JudgeState.CompileError:
                    return JudgeValue.CompileError;
                case JudgeState.SpecialJudgeProgramLost:
                case JudgeState.Crash:
                case JudgeState.ZeroTest:
                    return JudgeValue.JudgeError;
            }

            return JudgeValue.Processing;
        }
    }
    
    [fastCSharp.emit.dataSerialize(IsReferenceMember = false, IsMemberMap = false)]
    public class JudgeSetting
    {
        public int ProblemId;
        public DateTime LastUpdate;
        public JudgeType JudgeType = JudgeType.FileData;
        public string FormatString = string.Empty;
        public double Tolerance = 0;
        public CompileBase SpecialJudge;
        public CompileBase Solution;

        public bool Save(string fileName)
        {
            try
            {
                string json = this.ToJson();
                File.WriteAllText(fileName, json, Encoding.UTF8);
                return true;
            }
            catch { return false; }
        }

        public bool Load(string fileName)
        {
            try
            {
                string json = File.ReadAllText(fileName, Encoding.UTF8);
                return this.FromJson(json);
            }
            catch { return false; }
        }
    }

    public class CompileBase
    {
        public int JudgeId;
        public int ProblemId;
        public JudgeState State;
        public Language Language;
        public string ProgramContent;
        public string Message;
        public CompileType CompileType;
        public bool IsClearMessage;
        public string SourceFileName { get; set; }
        public string ExeFileName { get; set; }

        public bool CreateFile()
        {
            try
            {
                if (!string.IsNullOrEmpty(ExeFileName))
                {
                    DirectoryInfo dir = string.IsNullOrEmpty(Path.GetExtension(ExeFileName)) ? new DirectoryInfo(ExeFileName) : new DirectoryInfo(Path.GetDirectoryName(ExeFileName));

                    if (!dir.Exists)
                        dir.Create();
                }

                if (!string.IsNullOrEmpty(SourceFileName))
                {
                    DirectoryInfo dir = string.IsNullOrEmpty(Path.GetExtension(SourceFileName)) ? new DirectoryInfo(SourceFileName) : new DirectoryInfo(Path.GetDirectoryName(SourceFileName));

                    if (!dir.Exists)
                        dir.Create();
                }

                if (!string.IsNullOrEmpty(ProgramContent))
                    File.WriteAllText(SourceFileName, ProgramContent);

                return true;
            }
            catch { return false; }
        }

        public void CopyTo(CompileBase comp)
        {
            fastCSharp.emit.memberCopyer<CompileBase>.Copy(ref comp, this);
        }
    }
}
